(function() {

	var inputEx = YAHOO.inputEx, lang = YAHOO.lang, Event = YAHOO.util.Event, Dom = YAHOO.util.Dom;

	/**
	 * @class Create a Color picker input field
	 * @extends inputEx.Field
	 * @constructor
	 * @param {Object} options inputEx.Field options object
	 */
	inputEx.ColorField2 = function(options) {
		inputEx.ColorField2.superclass.constructor.call(this, options);
	};
	lang.extend(inputEx.ColorField2, inputEx.Field,
			/**
			 * @scope inputEx.ColorField2.prototype
			 */
				{

					/**
					 * How many color cells shall be shown in every line in the popup panel.
					 * if defined, cellPerLine*squareWidth+leftMargin = popupPanel.width, otherwise, there is a formula to determine cell size
					 */
					cellPerLine : 0,

					/** Width of every color cell. cellPerLine*squareWidth+leftMargin = popupPanel.width */
					cellWidth : 0,

					/** cellPerLine*squareWidth+leftMargin = popupPanel.width */
					leftMargin : 0,

					/** x:y ratio to list color cell, it is used only if cellPerLine is not defined. Default is 16:9 */
					ratio:0,

					/** Height of every color cell */
					cellHeight:0,

					/**
					 * Render the color button and the colorpicker popup
					 */
					renderComponent: function() {

						// A hidden input field to store the color code
						this.el = inputEx.cn('input', {
							type: 'hidden',
							name: this.options.name || '',
							value: this.options.value || this.options.colors[0]});

						// Create a colored area
						this.colorEl = inputEx.cn('div', {className: 'inputEx-ColorField-button'}, {backgroundColor: this.el.value});

						// Render the popup
						this.renderPopUp();

						// Elements are bound to divEl
						this.fieldContainer.appendChild(this.el);
						this.fieldContainer.appendChild(this.colorEl);
					},

					/**
					 * Register the click and blur events
					 */
					initEvents: function() {
						Event.addListener(this.colorEl, "click", this.toggleColorPopUp, this, true);
						Event.addListener(this.colorEl, "blur", this.closeColorPopUp, this, true);
					},

					/**
					 * Toggle the color picker popup
					 */
					toggleColorPopUp: function() {
						if (this.visible) {
							this.colorPopUp.style.display = 'none';
						}
						else {
							this.colorPopUp.style.display = 'block';
						}
						this.visible = !this.visible;
					},

					/**
					 * Call closeColorPopUp when field is removed
					 */
					close: function() {
						this.closeColorPopUp();
					},

					/**
					 * Close the popup
					 */
					closeColorPopUp: function() {
						this.colorPopUp.style.display = 'none';
						this.visible = false;
					},

					/**
					 * Render the color popup
					 */
					renderPopUp: function() {

						// display or not the title
						this.displayTitle = this.options.displayTitle || false;

						// set default color grid  to be used
						var defaultGrid = this.options.auto || 1;

						// set colors available
						this.colors = this.options.colors || this.setDefaultColors(defaultGrid);
						this.length = this.colors.length;

						// set PopUp size ratio (default 16/9 ratio)
						this.ratio = this.options.ratio || [16,9];

						// set color grid dimensions
						this.cellPerLine = this.options.cellPerLine || Math.ceil(Math.sqrt(this.length * this.ratio[0] / this.ratio[1]));
						this.squaresPerColumn = Math.ceil(this.length / this.cellPerLine);
						this.squaresOnLastLine = this.squaresPerLine - (this.squaresPerLine * this.squaresPerColumn - this.length);

						// set popup width
						this.cellWidth = this.options.cellWidth || 30;
						this.leftMargin = this.options.leftMargin || 10;

						var width = this.cellWidth * this.cellPerLine + this.leftMargin;

						// keep the visible state of the popup
						this.visible = false;

						// create the popup
						this.colorPopUp = inputEx.cn('div', {className: 'inputEx-ColorField-popup'}, {width: width + 'px', display: 'none'});

						// create the title
						if (this.displayTitle) {
							var div = inputEx.cn('div', null, null, inputEx.messages.selectColor);
							this.colorPopUp.appendChild(div);
						}

						var body = inputEx.cn('div');
						body.appendChild(this.renderColorGrid());
						this.colorPopUp.appendChild(body);

						this.divEl.appendChild(this.colorPopUp);
					},

					/**
					 * Get the value
					 */
					gettValue: function() {
						this.el.value = value;
						Dom.setStyle(this.colorEl, 'background-color', this.el.value);
					},

					/**
					 * Set the value
					 * @param {String} value Color to set
					 */
					setValue: function(value) {
						return this.el.value;
					},

					/**
					 * Set the colors to set in the picker
					 * @param {int} index Index of the palette to use
					 * @return {Array} List of colors to choose from
					 */
					setDefaultColors: function(index) {
						return inputEx.ColorField2.palettes[index - 1];
					},

					/**
					 * This creates a color grid
					 */
					renderColorGrid: function() {
						var table = inputEx.cn('table', null, {width: '100%'});
						var tbody = inputEx.cn('tbody');

						for (var i = 0; i < this.squaresPerColumn; i++) {
							var line = inputEx.cn('tr');
							for (var j = 0; j < this.cellPerLine; j++) {

								// spacer cells
								var cellHeight = this.options.cellHeight || 10;
								line.appendChild(inputEx.cn('td', null, {backgroundColor: '#fff', width:'5px', lineHeight: cellHeight + 'px', cursor: 'default'}, "&nbsp;"));

								// fill remaining space with empty and inactive squares
								var square = inputEx.cn('td', null, {backgroundColor: '#fff', lineHeight: cellHeight + 'px', cursor: 'default'}, '&nbsp;&nbsp;&nbsp;');

								inputEx.sn(square, null, {backgroundColor: '#' + this.colors[i * this.cellPerLine + j], cursor: 'pointer', margin:'10px'});
								YAHOO.util.Event.addListener(square, "mousedown", this.onColorClick, this, true);
								line.appendChild(square);
							}
							tbody.appendChild(line);

							// spacer line
							tbody.appendChild(inputEx.cn('tr', null, {height: '8px'}));
						}
						table.appendChild(tbody);
						return table;
					},

					/**
					 * Handle a color selection
					 * @param {Event} e The original click event
					 */
					onColorClick: function(e) {

						var square = Event.getTarget(e);//e.target;

						var couleur = Dom.getStyle(square, 'background-color');
						Dom.setStyle(this.colorEl, 'background-color', couleur);

						// set hidden field value
						// Convertit une chaine du style "rgb(255,142,0)" en hexadecimal du style "#FF8E00"
						var hexa = function (rgbcolor) {
							// Convertit un entier en hexa
							var DecToHex = function (n) {
								var tblCode = new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F");
								var BASE = 16;
								var Num = parseInt(n, 10);
								var i;
								var strHex = "";
								if (! isNaN(Num)) {
									if (Num == '') return "00";
									while (Num > 0) {
										i = 0;
										while (Num / Math.pow(BASE, i++) >= BASE);
										strHex += tblCode[Math.floor(Num / Math.pow(BASE, i - 1))];
										if (Num % BASE == 0) strHex += "0";
										Num = (Num % Math.pow(BASE, i - 1));
									}
									if (strHex.length == 1) {
										return '0' + strHex;
									}
									return strHex;
								}
								else return 0;
							};

							var rgb = rgbcolor.split(/([(,)])/);
							return '#' + DecToHex(rgb[2]) + DecToHex(rgb[4]) + DecToHex(rgb[6]);
						};

						this.el.value = hexa(couleur);

						// Overlay closure
						this.visible = !this.visible;
						this.colorPopUp.style.display = 'none';

						// Fire updated
						this.fireUpdatedEvt();
					}

				});

// Specific message for the container
	inputEx.messages.selectColor = "Select a color :";

	/**
	 * Default palettes
	 */
	inputEx.ColorField2.palettes = [
		["FFEA99","FFFF66","FFCC99","FFCAB2","FF99AD","FFD6FF","FF6666","E8EEF7","ADC2FF","ADADFF","CCFFFF","D6EAAD","B5EDBC","CCFF99"],
		["55AAFF","FFAAFF","FF7FAA","FF0202","FFD42A","F9F93B","DF8181","FEE3E2","D47FFF","2AD4FF","2AFFFF","AAFFD4"],
		["000000","993300","333300","003300","003366","000080","333399","333333","800000","FF6600","808000","008000","008080","0000FF","666699","808080","FF0000","FF9900","99CC00","339966","33CCCC","3366FF","800080","969696","FF00FF","FFCC00","FFFF00","00FF00","00FFFF","00CCFF","993366","C0C0C0","FF99CC","FFCC99","FFFF99","CCFFCC","CCFFFF","99CCFF","CC99FF","F0F0F0"]
	];

	/**
	 * Register this class as "color" type
	 */
	inputEx.registerType("color2", inputEx.ColorField2);

})();